#include <jni.h>
#include <string>

#include "MineFFmpeg.h"

// 有坑，会报错，必须混合编译
extern "C" {
    #include <libavformat/avformat.h>
}


JavaVM *javaVM = NULL;
MineCallJava *callJava = NULL;
MineFFmpeg *ffmpeg;
MinePlayStatus *playStatus;
bool nexit = true;

pthread_t threadStart;

//通过JNI_OnLoad  初始化JavaVM
extern "C"
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *resversed) {
    jint result = -1;

    JNIEnv *env;
    javaVM = vm;

    if (vm->GetEnv((void **) (&env), JNI_VERSION_1_6) != JNI_OK) {
        return result;
    }

    return JNI_VERSION_1_6;
}

extern "C"
JNIEXPORT void JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1parpared(JNIEnv *env, jobject instance,
                                                            jstring source_) {
    const char *source = env->GetStringUTFChars(source_, 0);


    if (NULL == ffmpeg) {
        if (NULL == callJava) {
            callJava = new MineCallJava(javaVM, env, &instance);
        }
        callJava->onCallLoad(MAIN_THREAD, true);
        playStatus = new MinePlayStatus();
        ffmpeg = new MineFFmpeg(callJava, source, playStatus);
        ffmpeg->parpared();
    }

//    env->ReleaseStringUTFChars(source_, source);
}


/**
 * threadStart 线程创建时的回调
 */

void *startCallBack(void *data) {
    MineFFmpeg *mineFFmpeg = static_cast<MineFFmpeg *>(data);
    mineFFmpeg->start();
    pthread_exit(&threadStart);
}
/**
 * 开始播放
 */
extern "C"
JNIEXPORT void JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1start(JNIEnv *env, jobject instance) {

    if (ffmpeg != NULL) {
//        ffmpeg->start();

        pthread_create(&threadStart, NULL, startCallBack, ffmpeg);
    }
}extern "C"
JNIEXPORT void JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1pause(JNIEnv *env, jobject thiz) {

    if (NULL != ffmpeg) {
        ffmpeg->pause();
    }
}extern "C"
JNIEXPORT void JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1resume(JNIEnv *env, jobject thiz) {
    if (NULL != ffmpeg) {
        ffmpeg->resume();
    }

}extern "C"
JNIEXPORT void JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1stop(JNIEnv *env, jobject thiz) {
    if (!nexit) {
        return;
    }
    jclass jlz = env->GetObjectClass(thiz);
    jmethodID jmid_next = env->GetMethodID(jlz, "onCallNext", "()V");


    if (NULL != ffmpeg) {
        ffmpeg->release();
        delete (ffmpeg);
        ffmpeg = NULL;
        if (callJava != NULL) {
            delete (callJava);
            callJava = NULL;
        }
        if (playStatus != NULL) {
            delete (playStatus);
            playStatus = NULL;
        }
    }
    nexit = true;
    env->CallVoidMethod(thiz, jmid_next);

}extern "C"
JNIEXPORT void JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1seek(JNIEnv *env, jobject thiz, jint seek) {

    if (ffmpeg != NULL) {
        ffmpeg->seek(seek);
    }
}extern "C"
JNIEXPORT jint JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1duration(JNIEnv *env, jobject thiz) {
    if (ffmpeg != NULL) {
        return ffmpeg->duration;
    }
    return 0;
}extern "C"
JNIEXPORT void JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1volume(JNIEnv *env, jobject thiz, jint persent) {
    if (NULL != ffmpeg) {
        ffmpeg->setVolume(persent);
    }

}extern "C"
JNIEXPORT void JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1mute(JNIEnv *env, jobject thiz, jint mute) {

    if(NULL!=ffmpeg){
        ffmpeg->setMute(mute);
    }
}extern "C"
JNIEXPORT void JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1speed(JNIEnv *env, jobject thiz, jfloat speed) {
    if(NULL!=ffmpeg){
        ffmpeg->setSpeed(speed);
    }
}
extern "C"
JNIEXPORT void JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1pitch(JNIEnv *env, jobject thiz, jfloat pitch) {
    if(NULL!=ffmpeg){
        ffmpeg->setPitch(pitch);
    }
}extern "C"
JNIEXPORT jint JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1samplerate(JNIEnv *env, jobject thiz) {
    if(NULL!=ffmpeg){
        return  ffmpeg->getSampleRate();
    }
    return 0;
}extern "C"
JNIEXPORT void JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1startStopRecord(JNIEnv *env, jobject thiz,
                                                                   jboolean start) {
    if(NULL!=ffmpeg){
        ffmpeg->startStopRecord(start);
    }

}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_renfei_mineplayer_MinePlayer_n_1cutaudioplay(JNIEnv *env, jobject thiz,
                                                                jint star_time, jint end_time,
                                                                jboolean show_pcm) {

    if(NULL!=ffmpeg){
        return  ffmpeg->curAudioPlay(star_time,end_time,show_pcm);
    }
    return false;
}